package gorm

import (
	"errors"
	"gitee.com/qzcsu/go-web-study/client"
	"gitee.com/qzcsu/go-web-study/model"
	"github.com/gin-gonic/gin"
	"github.com/google/uuid"
	"gorm.io/gorm"
	"log"
	"net/http"
	"strconv"
	"strings"
)

func AddUser(c *gin.Context) {
	userName := c.Query("user_name")
	userAddr := c.Query("user_addr")
	userAge := c.Query("user_age")
	userSex := c.Query("user_sex")

	userAgeInt, _ := strconv.ParseInt(userAge, 10, 16)
	userSexInt, _ := strconv.ParseInt(userSex, 10, 8)

	user := model.SysUserInfo{
		UserID:   strings.ReplaceAll(uuid.New().String(), "-", ""),
		UserName: userName,
		UserAddr: userAddr,
		UserSex:  int8(userSexInt),
		UserAge:  int16(userAgeInt),
	}

	// 手动指定插入哪几个字段
	//client.Db.Select("UserID", "UserName", "UserAddr", "UserAge").Create(&user)
	// 手动指出哪几个字段不进行插入
	client.Db.Create(&user)

	c.JSON(http.StatusOK, gin.H{
		"message": "success",
	})

	// 批量插入 grom2.0 默认支持，1.0不支持
	//client.Db.Create(&user)
}

func SelectUser(c *gin.Context) {
	//id := c.Query("id")
	//userAddr := c.Query("user_addr")

	var userList []*model.SysUserInfo
	//// Find 一定要放在最后
	//client.Db.Where("user_name = ?", c.Query("user_name")).Find(&userList)
	//client.Db.Where("sys_ctime between ? and ?", "2021-08-06 00:00:00", "2021-08-07 23:20:00").Find(&userList)
	// in 查询
	//client.Db.Where("user_name in (?)", c.Query("user_name_list")).Find(&userList)
	//// 主键查询
	//client.Db.Where([]int64{3, 5, 10}).Find(&userList)
	//// 只返回特定字段
	//client.Db.Select("user_name", "id").Where("user_name = ?", c.Query("user_name")).Find(&userList)
	//// 排序
	//client.Db.Where("user_name = ?", c.Query("user_name")).Order("user_age").Order("sys_ctime desc").Find(&userList)
	//// 分页查询 SELECT * FROM `sys_user_info` WHERE user_age > 10 LIMIT 3 OFFSET 2;
	//client.Db.Where("user_age > 10").Offset(2).Limit(3).Find(&userList)
	// Group & Having
	type Result struct {
		Sex   int8
		Count int
	}
	var result []*Result
	client.Db.Model(&model.SysUserInfo{}).Select("user_sex as Sex", "count(*) as count").Group("user_sex").Having("count(*) > 1").Find(&result)
	// distinct SELECT DISTINCT `user_name` FROM `sys_user_info` WHERE user_sex = 1
	client.Db.Where("user_sex = 1").Distinct("user_name").Find(&userList)
	// join SELECT a.user_name,b.user_age FROM sys_user_info a left join sys_user_info b on a.user_id = b.user_id WHERE `a`.`user_name` = '猪八戒'
	client.Db.Table("sys_user_info a").Select("a.user_name", "b.user_age").Joins("left join sys_user_info b on a.user_id = b.user_id").Where("a.user_name", c.Query("user_name")).Scan(&userList)

	rr := client.Db.Where("user_name = ?", "1000").Find(&userList)

	log.Printf("rr:%+v\n", rr)
	// 当 First、Last、Take 方法找不到记录时，GORM 会返回 ErrRecordNotFound 错误。如果发生了多个错误，你可以通过 errors.Is 判断错误是否为 ErrRecordNotFound
	log.Printf("rr.err:%v, is ErrRecordNotFound:%v\n", rr.Error, errors.Is(rr.Error, gorm.ErrRecordNotFound))
	log.Printf("rr.RowsAffected:%+v\n", rr.RowsAffected)

	c.JSON(http.StatusOK, gin.H{
		"message": "success",
		"data":    userList,
		"group":   result,
	})
}

func DelUser(c *gin.Context) {
	// 可与模型绑定前置hook函数
	// 根据主键删除
	client.Db.Delete(&model.SysUserInfo{}, 4)
	// 根据其它条件删除
	client.Db.Where("user_name", c.Query("user_name")).Delete(&model.SysUserInfo{})
	// 用户测试自己的sql 前提是创建数据库连接这个配置项为 true &gorm.client{DryRun: true}
	statement := client.Db.Where("user_age", 25).Delete(&model.SysUserInfo{}).Statement

	log.Printf("del statement dryRun 只打印sql，不真正执行:%+v\n", statement.SQL.String())

	c.JSON(http.StatusOK, gin.H{
		"message": "success",
	})
}

func UpdateUser(c *gin.Context) {
	// 可与模型绑定前置hook函数 BeforeUpdate BeforeSave
	// UpdateColumn/UpdateColumns 可跳过hook 函数与自动更新时间，类似与原生的sql操作
	// 根据主键更新多列
	user := &model.SysUserInfo{}
	user.ID = 1
	client.Db.Model(&user).Updates(model.SysUserInfo{UserName: "小麻皮", UserAddr: "深圳"})
	// 根据其它条件更新
	client.Db.Model(&model.SysUserInfo{}).Where("user_addr = ?", "shenzhen").Updates(model.SysUserInfo{UserName: "小皮球", UserAddr: "深圳"})
	// Omit 指定忽略Updates中map的指定的那些key更新
	client.Db.Model(&user).Omit("user_name").Updates(map[string]interface{}{"user_name": "小小飞", "user_age": 18})
	// Select 指定 Updates 中的map只有哪些key更新
	client.Db.Model(&user).Select("user_name", "user_age").Updates(model.SysUserInfo{UserName: "new_name", UserAge: 47})

	c.JSON(http.StatusOK, gin.H{
		"message": "success",
	})
}
